---
title: "Java Unsafe方法"
categories:
- java
tags:
---

<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org8aa6f5f">Intro</a></li>
<li><a href="#org41ac1ac">Thread control</a></li>
<li><a href="#org0e53f8c">CAS</a></li>
<li><a href="#orgaab3c41">Create an Instance of a Class Without Calling a Constructor</a></li>
<li><a href="#orge58a776">Native Memory Allocation</a></li>
<li><a href="#org4b286c3">Throwing Checked Exceptions Without Declaration</a></li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-org8aa6f5f">
<h2 id="org8aa6f5f">Intro</h2>
<div class="outline-text-2" id="text-org8aa6f5f">
<blockquote>
<p>
<a href="http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/">http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/</a>
<a href="https://dzone.com/articles/understanding-sunmiscunsafe">https://dzone.com/articles/understanding-sunmiscunsafe</a>
</p>
</blockquote>
<p>
这个类允许一些底层操作，例如直接内存操作、并发控制等。
</p>
<p>
这个类是被java核心类所使用的，无法通过常规方式获取它的实例，官方不建议使用。虽然它并不对外，但是几乎每个使用 java开发的工具、软件基础设施、高性能开发库都在底层使用了 sun.misc.Unsafe。 下面是上面链接中文档提到一个小列表：
</p>
<ul class="org-ul">
<li>Netty</li>
<li>Hazelcast</li>
<li>Cassandra</li>
<li>Mockito / EasyMock / JMock / PowerMock</li>
<li>Scala Specs</li>
<li>Spock</li>
<li>Robolectric</li>
<li>Grails</li>
<li>Neo4j</li>
<li>Spring Framework</li>
<li>Akka</li>
<li>Apache Kafka</li>
<li>Apache Wink</li>
<li>Apache Storm</li>
<li>Apache Hadoop</li>
<li>Apache Continuum</li>
<li>…</li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-org41ac1ac">
<h2 id="org41ac1ac">Thread control</h2>
<div class="outline-text-2" id="text-org41ac1ac">
<p>
线程控制方法 {% raw %} park {% endraw %} {% raw %} unpark {% endraw %}
调用 {% raw %} park {% endraw %} 方法后，指定的线程将阻塞，直到超时或中断。
{% raw %} unpark {% endraw %} 能够恢复挂起的线程。
{% raw %} java.util.concurrent.locks.LockSupport {% endraw %} 类提供了这些方法的封装，使用我们不用去想歪获取Unsafe对象。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-org0e53f8c">
<h2 id="org0e53f8c">CAS</h2>
<div class="outline-text-2" id="text-org0e53f8c">
<p>
包括一些 {% raw %} compareAnd* {% endraw %} 的方法。下面方法表示：obj对象中的offset处的4个字节(int),如果当前值是expect，则修改为update。
offset能够通过 {% raw %} Unsafe.objectFieldOffset() {% endraw %} 方法获得。
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-style: italic;">/*** </span>
<span style="font-style: italic;"> * Compares the value of the integer field at the specified offset </span>
<span style="font-style: italic;"> * in the supplied object with the given expected value, and updates </span>
<span style="font-style: italic;"> * it if they match.  The operation of this method should be atomic, </span>
<span style="font-style: italic;"> * thus providing an uninterruptible way of updating an integer field. </span>
<span style="font-style: italic;"> *</span>
<span style="font-style: italic;"> * 在obj的offset位置比较integer field和期望的值，如果相同则更新。这个方法 </span>
<span style="font-style: italic;"> * 的操作应该是原子的，因此提供了一种不可中断的方式更新integer field。 </span>
<span style="font-style: italic;"> *  </span>
<span style="font-style: italic;"> * </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">@param</span><span style="font-style: italic;"> obj the object containing the field to modify. </span>
<span style="font-style: italic;"> *            包含要修改field的对象 </span>
<span style="font-style: italic;"> * </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">@param</span><span style="font-style: italic;"> offset the offset of the integer field within </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;code&gt;</span><span style="font-style: italic;">obj</span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;/code&gt;</span><span style="font-style: italic;">. </span>
<span style="font-style: italic;"> *               </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;code&gt;</span><span style="font-style: italic;">obj</span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;/code&gt;</span><span style="font-style: italic;">中整型field的偏移量 </span>
<span style="font-style: italic;"> * </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">@param</span><span style="font-style: italic;"> expect the expected value of the field. </span>
<span style="font-style: italic;"> *               希望field中存在的值 </span>
<span style="font-style: italic;"> * </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">@param</span><span style="font-style: italic;"> update the new value of the field if it equals </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;code&gt;</span><span style="font-style: italic;">expect</span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">&lt;/code&gt;</span><span style="font-style: italic;">. </span>
<span style="font-style: italic;"> *           如果期望值expect与field的当前值相同，设置filed的值为这个新值 </span>
<span style="font-style: italic;"> * </span><span style="font-weight: bold; font-style: italic; text-decoration: underline;">@return</span><span style="font-style: italic;"> true if the field was changed. </span>
<span style="font-style: italic;"> *                             如果field的值被更改 </span>
<span style="font-style: italic;"> */</span>  
<span style="font-weight: bold;">public</span> <span style="font-weight: bold;">native</span> <span style="font-weight: bold; text-decoration: underline;">boolean</span> <span style="font-weight: bold;">compareAndSwapInt</span>(<span style="font-weight: bold; text-decoration: underline;">Object</span> <span style="font-weight: bold; font-style: italic;">obj</span>, <span style="font-weight: bold; text-decoration: underline;">long</span> <span style="font-weight: bold; font-style: italic;">offset</span>,<span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">expect</span>, <span style="font-weight: bold; text-decoration: underline;">int</span> <span style="font-weight: bold; font-style: italic;">update</span>);  
</pre>
</div>
</div>
</div>
<div class="outline-2" id="outline-container-orgaab3c41">
<h2 id="orgaab3c41">Create an Instance of a Class Without Calling a Constructor</h2>
<div class="outline-text-2" id="text-orgaab3c41">
<p>
反序列化时创建对对像，绕过构造方法，以提高效率。
</p>
</div>
</div>
<div class="outline-2" id="outline-container-orge58a776">
<h2 id="orge58a776">Native Memory Allocation</h2>
</div>
<div class="outline-2" id="outline-container-org4b286c3">
<h2 id="org4b286c3">Throwing Checked Exceptions Without Declaration</h2>
<div class="outline-text-2" id="text-org4b286c3">
<p>
There are some other interesting methods to find in Unsafe. Did you ever want to throw a specific exception to be handled in a lower layer but you high layer interface type did not declare this checked exception? Unsafe#throwException allows to do so:
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; text-decoration: underline;">@Test</span>(expected = Exception.<span style="font-weight: bold;">class</span>)
<span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">testThrowChecked</span>() <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">Exception</span> {
  throwChecked();
}

<span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">void</span> <span style="font-weight: bold;">throwChecked</span>() {
  unsafe.throwException(<span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">Exception</span>());
}
</pre>
</div>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
